﻿using Basic.HrCollect;
using Basic.HrModel.DB;
using Basic.HrModel.Dept;
using Basic.HrModel.Emp;
using Basic.HrRemoteModel;
using Basic.HrRemoteModel.DeptChange.Model;
using Basic.HrRemoteModel.Emp.Model;
using Basic.HrService.Interface;
using WeDonekRpc.Client;
using WeDonekRpc.Helper;
using WeDonekRpc.Model;

namespace Basic.HrService.lmpl
{
    internal class DeptChangeService : IDeptChangeService
    {
        private readonly IEmpCollect _Emp;
        private readonly IDeptCollect _Dept;
        private readonly ITitleDicItemCollect _Title;
        private readonly IEmpTitleCollect _EmpTitle;
        private readonly IPostDicItemCollect _Post;
        private readonly IEmpPostCollect _EmpPost;

        public DeptChangeService ( IEmpCollect emp,
            IDeptCollect dept,
            ITitleDicItemCollect title,
            IPostDicItemCollect post,
            IEmpPostCollect empPost,
            IEmpTitleCollect empTitle )
        {
            this._EmpPost = empPost;
            this._Post = post;
            this._Emp = emp;
            this._Dept = dept;
            this._Title = title;
            this._EmpTitle = empTitle;
        }

        public ChangeDeptTree GetDept ( long deptId, bool? isUnit )
        {
            DBDept dept = this._Dept.Get(deptId);
            DeptBase[] depts = this._Dept.GetDepts<DeptBase>(new DeptGetParam
            {
                IsAllChildren = true,
                Status = new HrDeptStatus[]
                {
                    HrDeptStatus.启用
                },
                CompanyId = [dept.CompanyId],
                IsUnit = isUnit,
                ParentId = [deptId]
            });
            long[] ids = depts.ConvertAll(a => a.Id).Add(dept.Id);
            Dictionary<long, int> empNum = this._Emp.GetDeptEmpNum(ids);
            return new ChangeDeptTree
            {
                DeptName = dept.ShortName.GetValueOrDefault(dept.DeptName),
                EmpNum = empNum.GetValueOrDefault(deptId),
                Children = depts.ToTree(deptId, empNum),
                Id = dept.Id,
                IsUnit = dept.IsUnit,
            };
        }
        public PagingResult<DisbandDeptEmp> Query ( DeptDisbandedArg arg, IBasicPage paging )
        {
            DBDept dept = this._Dept.Get(arg.DeptId);
            long[] deptId = this._Dept.GetEnableSubId(dept);
            if ( dept.IsUnit == false )
            {
                deptId = deptId.Add(dept.Id);
            }
            EmpQuery param = new EmpQuery
            {
                CompanyId = arg.CompanyId,
                DeptId = deptId,
                IsEntry = false,
                Status = new HrEmpStatus[]
                {
                    HrEmpStatus.启用,
                    HrEmpStatus.起草
                }
            };
            EmpDto[] emps = this._Emp.Query<EmpDto>(param, paging, out int count);
            if ( emps.IsNull() )
            {
                return new PagingResult<DisbandDeptEmp>();
            }
            DisbandDeptEmp[] dtos = emps.ConvertMap<EmpDto, DisbandDeptEmp>();
            long[] empId = dtos.ConvertAll(a => a.EmpId);
            var titles = this._EmpTitle.GetEmpDeptTitle(empId, deptId, a => new
            {
                a.EmpId,
                a.UnitId,
                a.DeptId,
                a.TitleCode
            });
            var posts = this._EmpPost.GetEmpDeptPost(empId, deptId, a => new
            {
                a.EmpId,
                a.UnitId,
                a.DeptId,
                a.PostCode
            });
            if ( dept.IsUnit == false )
            {
                deptId = deptId.Add(dept.UnitId);
            }
            Dictionary<long, string> deptName = this._Dept.GetDeptName(deptId);
            Dictionary<string, string> titleName = this._Title.GetTitleNames(titles.ConvertAll(a => a.TitleCode));
            Dictionary<string, string> postName = this._Post.GetPostName(posts.ConvertAll(a => a.PostCode));
            dtos.ForEach(c =>
            {
                var title = titles.FindAll(a => a.EmpId == c.EmpId);
                if ( title.Length > 0 )
                {
                    c.Title = title.ConvertAll(a => string.Format("{2} {0}({1})", deptName[a.DeptId], deptName[a.UnitId], titleName[a.TitleCode]));
                }
                var post = posts.FindAll(a => a.EmpId == c.EmpId);
                if ( post.Length > 0 )
                {
                    c.Post = post.ConvertAll(a => string.Format("{2} {0}({1})", deptName[a.DeptId], deptName[a.UnitId], postName[a.PostCode]));
                }
                c.DeptName = deptName.GetValueOrDefault(c.DeptId);
                c.UnitName = deptName.GetValueOrDefault(c.UnitId);
            });
            return new PagingResult<DisbandDeptEmp>(dtos, count);
        }
    }
}
